<?php



/**
 * Radcodes - SocialEngine Module
 *
 * @category   Application_Extensions
 * @package    Gmap
 * @copyright  Copyright (c) 2009-2010 Radcodes LLC (http://www.radcodes.com)
 * @license    http://www.radcodes.com/license/
 * @version    $Id$
 * @author     Vincent Van <vincent@radcodes.com>
 */
 
 
 
class Gmap_Api_Core extends Core_Api_Abstract
{
	// image (main)
  const IMAGE_WIDTH = 720;
  const IMAGE_HEIGHT = 720;

  // image (thumb.normal)
  const THUMB_WIDTH = 140;
  const THUMB_HEIGHT = 160;
  
  // image (thumb.icon)
  const ICON_WIDTH = 48;
  const ICON_HEIGHT = 48;
  
  // image (thumb.profile)
  const PROFILE_WIDTH = 200;
  const PROFILE_HEIGHT = 400;
  
  /**
   * Gets a paginator for approved - mappable gmaps
   *
   * @param Core_Model_Item_Abstract $user The user to get the messages for
   * @return Zend_Paginator
   */  
  public function getMappableGmapsPaginator($params = array(), $options = null)
  {
  	$params['mappable'] = 1;
  	return $this->getGmapsPaginator($params, $options);
  }
  
  // Select
  /**
   * Gets a paginator for gmaps
   *
   * @param Core_Model_Item_Abstract $user The user to get the messages for
   * @return Zend_Paginator
   */
  public function getGmapsPaginator($params = array(), $options = null)
  {
    $paginator = Zend_Paginator::factory($this->getGmapsSelect($params, $options));
    if( !empty($params['page']) )
    {
      $paginator->setCurrentPageNumber($params['page']);
    }
    if( !empty($params['limit']) )
    {
      $paginator->setItemCountPerPage($params['limit']);
    }
    return $paginator;
  }

  /**
   * Gets a select object for the user's gmap entries
   *
   * @param Core_Model_Item_Abstract $user The user to get the messages for
   * @return Zend_Db_Table_Select
   */
  public function getGmapsSelect($params = array(), $options = null)
  {
    $table = Engine_Api::_()->getDbtable('gmaps', 'gmap');
    $rName = $table->info('name');

    $tmTable = Engine_Api::_()->getDbtable('TagMaps', 'core');
    $tmName = $tmTable->info('name');

    $searchTable = Engine_Api::_()->fields()->getTable('gmap', 'search')->info('name');

    
    
    if (!empty($params['order']) && $params['order'] == 'random') {
      $order_expr = new Zend_Db_Expr('RAND()');
    }
    else {
      $order = $rName.'.'.( !empty($params['order']) ? $params['order'] : 'creation_date' );
      $order_direction = !empty($params['order_direction']) ? $params['order_direction'] : 'DESC';
      $order_expr = "$order $order_direction";
    }      
    
    if (!empty($params['pre_order']))
    {
    	$pre_orders = array(
        1 => array("{$rName}.sponsored DESC"), // Sponsored gmaps, then user preference",
        2 => array("{$rName}.sponsored DESC","{$rName}.featured DESC"), // "Sponsored gmaps, featured gmaps, then user preference",
        3 => array("{$rName}.featured DESC"), // "Featured gmaps, then user preference",
        4 => array("{$rName}.featured DESC","{$rName}.sponsored DESC"), // "Featured gmaps, sponsored gmaps, then user preference",
    	);
    	if (isset($pre_orders[$params['pre_order']]))
    	{
    		$order_expr = array_merge($pre_orders[$params['pre_order']], array($order_expr));
    	}
    }
    
   // print_r($order_expr);
    

    $select = $table->select()
      ->order( $order_expr );

    // Process options
    $tmp = array();
    foreach( $params as $k => $v ) {
      if( null == $v || '' == $v || (is_array($v) && count(array_filter($v)) == 0) ) {
        continue;
      } else if( false !== strpos($k, '_field_') ) {
        list($null, $field) = explode('_field_', $k);
        $tmp['field_' . $field] = $v;
      } else if( false !== strpos($k, '_alias_') ) {
        list($null, $alias) = explode('_alias_', $k);
        $tmp[$alias] = $v;
      } else {
        $tmp[$k] = $v;
      }
    }
    $params = $tmp; 
    
    // Build search part of query
    $searchParts = Engine_Api::_()->fields()->getSearchQuery('gmap', $params);
    if (!empty($searchParts))
    {
      $select = $select
        ->setIntegrityCheck(false)
        ->from($rName)
        ->joinLeft($searchTable, "$searchTable.item_id = $rName.gmap_id")
        ->group("$rName.gmap_id");    	
      foreach( $searchParts as $k => $v ) 
	    {
	      $select = $select->where("`{$searchTable}`.{$k}", $v);
	    }
    }
    
    if( !empty($params['user_id']) && is_numeric($params['user_id']) )
    {
      $select->where($rName.'.owner_id = ?', $params['user_id']);
    }

    if( !empty($params['user']))
    {
      $user = Engine_Api::_()->user()->getUser($params['user']);   
      $select->where($rName.'.owner_id = ?', $user->getIdentity());
    }

    if( isset($params['users']) )
    {
      $str = (string) ( is_array($params['users']) ? "'" . join("', '", $params['users']) . "'" : $params['users'] );
      $select->where($rName.'.owner_id in (?)', new Zend_Db_Expr($str));
    }

    if (!empty($params['username']))
    {
    	$userTable = Engine_Api::_()->getDbtable('users', 'user')->info('name');

      $select = $select
        ->setIntegrityCheck(false)
        ->from($rName)
        ->joinLeft($userTable, "$userTable.user_id = $rName.owner_id")
        ->where($userTable.'.username LIKE ?', '%' . $params['username'] . '%');
    }
    
    if( !empty($params['tag']) )
    {
    	$select = $select
        ->setIntegrityCheck(false)
        ->from($rName)
        ->joinLeft($tmName, "$tmName.resource_id = $rName.gmap_id")
        ->where($tmName.'.resource_type = ?', 'gmap')
        ->where($tmName.'.tag_id = ?', $params['tag']);
    }

    if( !empty($params['category']) )
    {
      $select->where($rName.'.category_id = ?', $params['category']);
    }
    
    // Could we use the search indexer for this?
    if( !empty($params['search']) )
    {
      $select->where($rName.".title LIKE ? OR ".$rName.".description LIKE ?", '%'.$params['search'].'%');
    }

    if( !empty($params['start_date']) )
    {
      $select->where($rName.".creation_date > ?", date('Y-m-d', $params['start_date']));
    }

    if( !empty($params['end_date']) )
    {
      $select->where($rName.".creation_date < ?", date('Y-m-d', $params['end_date']));
    }
    
    $bool_keys = array('mappable', 'featured', 'sponsored', 'home');
    foreach ($bool_keys as $bool_key)
    {
      if( isset($params[$bool_key]) && strlen($params[$bool_key]))
      {
        $select->where($rName.'.'.$bool_key.' = ?', $params[$bool_key]);
      }
    }
    
    if (isset($params['exclude_gmap_ids']) and !empty($params['exclude_gmap_ids']))
    {
    	$select->where($rName.'.gmap_id NOT IN (?)', $params['exclude_gmap_ids']);
    }
    
    if (isset($params['location']) && strlen($params['location']))
    {
    	$location = $params['location'];
	    $google_map = new Radcodes_Lib_Google_Map();
	    $geocoded_address = $google_map->geocode($location);
	    if ($geocoded_address)
	    {
	    	if ($geocoded_address->hasType(Radcodes_Lib_Google_Map_GeocodedAddress::TYPE_COUNTRY))
	    	{
	    		$select->where($rName.'.country IN (?)', array($geocoded_address->getCountry(), $geocoded_address->getCountryCode()));
	    	}
	    	else if ($geocoded_address->hasType(Radcodes_Lib_Google_Map_GeocodedAddress::TYPE_PROVINCE))
	    	{
	    		$select->where($rName.'.state IN (?)', array($geocoded_address->getProvince(), $geocoded_address->getProvinceCode()));
	    	}
	    	else
	    	{
	    		$coord = $geocoded_address->getCoord();
	    		if (empty($params['distance'])) $params['distance'] = 50;
	    		
	    		if (isset($params['distance_unit'])) {
	    			if ($params['distance_unit'] == Radcodes_Lib_Helper_Unit::UNIT_MILE) {
	    				$params['distance'] = Radcodes_Lib_Helper_Unit::mileToKilometer($params['distance']);
	    			}
	    		}
	    		
	    		$select = $coord->getCriteriaInRadius($rName.'.lat', $rName.'.lng', $params['distance'], $select);
	    	}
	    }
    }
    
   // Engine_Api::_()->getApi('debug','radcodes')->log($params,'getGmapsSelect params');
   // Engine_Api::_()->getApi('debug','radcodes')->log($select->__toString(),'getGmapsSelect select query');
    
    
    return $select;
  }


  public function getCategories()
  {
    $table = Engine_Api::_()->getDbtable('categories', 'gmap');
    $categories = $table->fetchAll($table->select()->order('order'));
    
    return $categories;  
  }

  public function getCategory($category_id)
  {
  	static $categories = array();
  	
  	if (!isset($categories[$category_id]))
  	{
  		$categories[$category_id] = Engine_Api::_()->getDbtable('categories', 'gmap')->find($category_id)->current();
  	}
  	
    return $categories[$category_id];
  }

  public function getUserCategories($user_id)
  {
    $table  = Engine_Api::_()->getDbtable('categories', 'gmap');
    $uName = Engine_Api::_()->getDbtable('gmaps', 'gmap')->info('name');
    $iName = $table->info('name');

    $select = $table->select()
      ->setIntegrityCheck(false)
      ->from($iName, array('category_name'))
      ->joinLeft($uName, "$uName.category_id = $iName.category_id")
      ->group("$iName.category_id")
      ->where($uName.'.owner_id = ?', $user_id);

    return $table->fetchAll($select);
  }

  public function convertCategoriesToArray($categories)
  {
    $categories_prepared = array();
    foreach ($categories as $category){
      $categories_prepared[$category->category_id]= $category->category_name;
    }
    return $categories_prepared;
  }
  
  function getArchiveList($params = array())
  {

    $table = Engine_Api::_()->getDbtable('gmaps', 'gmap');
    $rName = $table->info('name');

    $select = $table->select()
      ->from($rName, array("DATE_FORMAT(creation_date, '%Y-%m') as period", "COUNT(*) as total"))
      ->group('period')
      ->order("period DESC");

    if( !empty($params['user_id']) && is_numeric($params['user_id']) )
    {
      $select->where($rName.'.owner_id = ?', $params['user_id']);
    }
    if( isset($params['mappable']) && strlen($params['mappable']) )
    {
      $select->where($rName.'.mappable = ?', $params['mappable']);
    }
   
    $stmt = $select->query();
    $results = $stmt->fetchAll();
    
    return $results;
  }

  public function createPhoto($params, $photo)
  {
    if( $photo instanceof Storage_Model_File )
    {
      $params['file_id'] = $photo->getIdentity();
    }

    else
    {
      //Engine_Api::_()->getApi('debug','radcodes')->log($params,'createPhoto $params=');
    	//Engine_Api::_()->getApi('debug','radcodes')->log($photo,'createPhoto $photo=');
    	
	    if( $photo instanceof Zend_Form_Element_File ) {
	      $file = $photo->getFileName();
	    } else if( is_array($photo) && !empty($photo['tmp_name']) ) {
	      $file = $photo['tmp_name'];
	    } else if( is_string($photo) && file_exists($photo) ) {
	      $file = $photo;
	    } else {
	      throw new Gmap_Model_Exception('invalid argument passed to Gmap_Api_Core::createPhoto');
	    }
    	
	    if (is_array($photo) && !empty($photo['name'])) {
	    	$name = basename($photo['name']);
	    }
	    else {
	    	$name = basename($file);
	    }
    	
    	$path = APPLICATION_PATH . DIRECTORY_SEPARATOR . 'temporary';
    	
      $mainName = $path.'/m_'.$name;
      $profileName = $path.'/p_'.$name;
      $thumbName = $path.'/t_'.$name;
      $iconName = $path.'/is_'.$name;	    
	    

      $image = Engine_Image::factory();
      $image->open($file)
          ->resize(self::IMAGE_WIDTH, self::IMAGE_HEIGHT)
          ->write($mainName)
          ->destroy();

      $image = Engine_Image::factory();
      $image->open($file)
          ->resize(self::PROFILE_WIDTH, self::PROFILE_HEIGHT)
          ->write($profileName)
          ->destroy(); 
          
      $image = Engine_Image::factory();
      $image->open($file)
          ->resize(self::THUMB_WIDTH, self::THUMB_HEIGHT)
          ->write($thumbName)
          ->destroy();

	    // Resize image (icon)
	    $image = Engine_Image::factory();
	    $image->open($file);
	
	    $size = min($image->height, $image->width);
	    $x = ($image->width - $size) / 2;
	    $y = ($image->height - $size) / 2;
	
	    $image->resample($x, $y, $size, $size, self::ICON_WIDTH, self::ICON_HEIGHT)
	      ->write($iconName)
	      ->destroy();   

          
      // Store photos
      $photo_params = array(
        'parent_id' => $params['gmap_id'],
        'parent_type' => 'gmap',
      );

      $photoFile = Engine_Api::_()->storage()->create($mainName, $photo_params);
      $profileFile = Engine_Api::_()->storage()->create($profileName, $photo_params);
      $thumbFile = Engine_Api::_()->storage()->create($thumbName, $photo_params);
      $iconFile = Engine_Api::_()->storage()->create($iconName, $photo_params);
      
      $photoFile->bridge($profileFile, 'thumb.profile');
      $photoFile->bridge($thumbFile, 'thumb.normal');
      $photoFile->bridge($iconFile, 'thumb.icon');
      
      $params['file_id'] = $photoFile->file_id;
      //$params['photo_id'] = $photoFile->file_id;

      // Remove temp files
      @unlink($mainName);
      @unlink($profileName);
      @unlink($thumbName);
      @unlink($iconName);
      
    }

    $row = Engine_Api::_()->getDbtable('photos', 'gmap')->createRow();
    $row->setFromArray($params);
    $row->save();
    return $row;
  }


  public function getPopularTags($options = array())
  {
    $tags = Engine_Api::_()->radcodes()->getPopularTags('gmap', $options);
    return $tags;
  }
  
  public function clearGmapHome($user_id)
  {
  	$params = array(
  	 'user_id' => $user_id,
  	 'home' => 1
  	);
  	$gmaps = $this->getGmapsPaginator($params);
  	if ($gmaps->getTotalItemCount())
  	{
	  	foreach ($gmaps as $gmap)
	    {
	      $gmap->home = 0;
	      $gmap->save();
	    }
  	}

  }
  
  public function hasGmapHome($user_id)
  {
    $params = array(
  	 'user_id' => $user_id,
  	 'home' => 1
  	);
  	$gmaps = $this->getGmapsPaginator($params);
  	return $gmaps->getTotalItemCount() > 0;
  }
}